import 'package:path/path.dart' as path;
import 'package:recase/recase.dart';
import 'package:serverpod_cli/src/analyzer/protocol_definition.dart';
import 'package:serverpod_cli/src/generator/dart/server_code_generator.dart';
import 'package:test/test.dart';

import '../../../test_util/builders/generator_config_builder.dart';
import '../../../test_util/builders/model_class_definition_builder.dart';

const projectName = 'example_project';
final config = GeneratorConfigBuilder().withName(projectName).build();
const generator = DartServerCodeGenerator();

void main() {
  var expectedFileName = path.join(
    'lib',
    'src',
    'generated',
    'protocol.dart',
  );
  group(
    'Given classes with a circular relation when generating protocol files',
    () {
      /**
     * Citizen -> Company -> Town -> Citizen
     */
      var citizen = 'citizen';
      var company = 'company';
      var town = 'town';
      var models = [
        ModelClassDefinitionBuilder()
            .withClassName(citizen.sentenceCase)
            .withFileName(citizen)
            .withTableName(citizen)
            .withSimpleField('name', 'String')
            .withObjectRelationField(company, company.sentenceCase, company)
            .build(),
        ModelClassDefinitionBuilder()
            .withClassName(company.sentenceCase)
            .withFileName(company)
            .withTableName(company)
            .withSimpleField('name', 'String')
            .withObjectRelationField(town, town.sentenceCase, town)
            .build(),
        ModelClassDefinitionBuilder()
            .withClassName(town.sentenceCase)
            .withFileName(town)
            .withTableName(town)
            .withSimpleField('name', 'String')
            .withObjectRelationField('mayor', citizen.sentenceCase, citizen)
            .build(),
      ];

      var protocolDefinition = ProtocolDefinition(
        endpoints: [],
        models: models,
      );

      var codeMap = generator.generateProtocolCode(
        protocolDefinition: protocolDefinition,
        config: config,
      );

      test(
        'then expected files is created.',
        () {
          expect(codeMap[expectedFileName], isNotNull);
        },
      );
    },
  );
}
